#pragma once

#include <CameraApi.h>  
#include <rclcpp/logging.hpp>  
#include <string> 
#include <cstdint>  

namespace mindvision_camera {

class MVCameraSDK {
public:
  // -------------------------- 构造/析构 --------------------------
  /**
   * @brief 默认构造函数
   * @note 初始化内部成员变量（如相机句柄设为-1，避免野指针）
   */
  MVCameraSDK(rclcpp::Logger logger);

  /**
   * @brief 析构函数
   * @note 自动释放相机资源（调用unInit()），防止内存泄漏
   */
  ~MVCameraSDK();

  // -------------------------- 相机生命周期管理 --------------------------
  /**
   * @brief 初始化相
   * @param logger ROS节点的日志器
   * @return bool 初始化成功返回true，失败返回false
   */
  bool init();

  /**
   * @brief 释放相机资源
   * @note 关闭相机、释放缓冲区，避免SDK资源泄漏
   */
  void unInit();

  // -------------------------- 参数设置接口 --------------------------
  /**
   * @brief 设置曝光时间（微秒）
   * @param exposure_time 曝光时间值（需在相机支持的范围内）
   * @return bool 设置成功返回true，失败返回false
   */
  bool setExposureTime(double exposure_time);

  /**
   * @brief 设置模拟增益
   * @param analog_gain 增益值（整数，需在相机支持的范围内）
   * @return bool 设置成功返回true，失败返回false
   */
  bool setAnalogGain(int analog_gain);

  /**
   * @brief 设置RGB增益（三通道同时设置）
   * @param r_gain 红色通道增益
   * @param g_gain 绿色通道增益
   * @param b_gain 蓝色通道增益
   * @return bool 设置成功返回true，失败返回false
   */
  bool setRgbGain(int r_gain, int g_gain, int b_gain);

  /**
   * @brief 设置饱和度
   * @param saturation 饱和度值（整数，需在相机支持的范围内）
   * @return bool 设置成功返回true，失败返回false
   */
  bool setSaturation(int saturation);

  /**
   * @brief 设置伽马值
   * @param gamma 伽马值（整数，需在相机支持的范围内）
   * @return bool 设置成功返回true，失败返回false
   */
  bool setGamma(int gamma);

  /**
   * @brief 设置相机VID/PID（用于USB重置）
   * @param vid_pid 格式为"0xXXXX:0xXXXX"的字符串（如"0x1BDA:0x0011"）
   */
  void setVidPid(const std::string &vid_pid);

  // -------------------------- 图像获取与处理接口 --------------------------
  /**
   * @brief 获取相机图像缓冲区（需配合releaseImageBuffer()使用）
   * @param[out] frame_info 输出图像帧头信息（分辨率、帧率等）
   * @param[out] buffer 输出图像数据指针（SDK分配的缓冲区）
   * @param timeout_ms 超时时间（毫秒，默认1000ms）
   * @return bool 获取成功返回true，失败（超时/未初始化）返回false
   */
  bool getImageBuffer(tSdkFrameHead &frame_info, uint8_t *&buffer, int timeout_ms = 1000);

  /**
   * @brief 处理图像（ISP转换为RGB8 + 图像翻转）
   * @param[out] dest_buffer 目标缓冲区（外部提供，存储处理后的RGB数据）
   * @param flip_image 是否翻转图像（true=翻转，false=不翻转）
   */
  void processImage(uint8_t *dest_buffer, bool flip_image);

  /**
   * @brief 释放图像缓冲区（必须在getImageBuffer()后调用，避免内存泄漏）
   */
  void releaseImageBuffer();

  // -------------------------- 辅助功能接口 --------------------------

  /**
   * @brief 重置USB设备（相机连接异常时使用）
   */
  void resetUsb();

  /**
   * @brief 获取相机能力描述
   * @return tSdkCameraCapbility 相机能力结构体（含参数最小/最大值）
   */
  tSdkCameraCapbility getCapability() const;

  /**
   * @brief 获取当前模拟增益
   * @return int 当前增益值（未初始化返回0）
   */
  int getCurrentAnalogGain();

  /**
   * @brief 获取当前RGB增益
   * @param[out] r 红色通道增益
   * @param[out] g 绿色通道增益
   * @param[out] b 蓝色通道增益
   */
  void getCurrentRgbGain(int &r, int &g, int &b);

  /**
   * @brief 获取当前饱和度
   * @return int 当前饱和度值（未初始化返回0）
   */
  int getCurrentSaturation();

  /**
   * @brief 获取当前伽马值
   * @return int 当前伽马值（未初始化返回0）
   */
  int getCurrentGamma();

  /**
   * @brief 获取曝光行时间
   * @return double 行时间（微秒，未初始化返回0.0）
   */
  double getExposureLineTime();

  /**
   * @brief 检查相机是否已初始化
   * @return bool 已初始化返回true，未初始化返回false
   */
  bool isCameraInitialized() const;

private:
  // -------------------------- 内部成员变量 --------------------------
  rclcpp::Logger logger_;            // ROS日志器
  int h_camera_;                     // 相机句柄
  uint8_t *pby_buffer_;              // 图像缓冲区指针
  tSdkCameraCapbility t_capability_; // 相机能力结构体
  tSdkFrameHead s_frame_info_;       // 当前图像帧头
  int vid_;                          // USB厂商ID
  int pid_;                          // USB产品ID

  // -------------------------- 内部辅助函数 --------------------------

  /**
   * @brief 解析VID/PID字符串
   * @param vid_pid 输入字符串（格式"0xXXXX:0xXXXX"）
   * @param[out] vid 解析后的VID（十进制）
   * @param[out] pid 解析后的PID（十进制）
   * @return bool 解析成功返回true，失败返回false
   */
  bool parseVidPid(const std::string &vid_pid, int &vid, int &pid);
};

}  // namespace mindvision_camera